﻿using System;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

using PlanningGIS.Util.Convertor;
using PlanningGIS.ArcGIS;
using PlanningGIS.Util.Log;
using PlanningGIS.Engine.Controls;

namespace PlanningGIS.DataCheck.model
{
    /// <summary>
    /// 水系名称2(3)不一致检查（对于湖泊；荡、漾、湾；运行中水库或建设中水库时，判断这些面是否和其他水系面交汇，
    /// 若是，检查其名称2（或名称3）是否与他相交的水系面一致）
    /// </summary>
    public class HydNamesCheck : Check
    {
        public int Check(string errType, IFeatureLayer pFeatLyrPy, IFeatureLayer pFeatLyrLn, IGeometry pGeometry,
            string whereClause, string fcodename, string fnamename, string fname2name, string fname3name)
        {
            IFeatureClass pFeatClsPy = pFeatLyrPy.FeatureClass;
            IFeatureClass pFeatClsLn = pFeatLyrLn.FeatureClass;

            if (pFeatClsLn.ShapeType != esriGeometryType.esriGeometryPolyline)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrLn.Name + "]图层不是线状图层，检查失败！");
                return -1;
            }

            if (pFeatClsPy.ShapeType != esriGeometryType.esriGeometryPolygon)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrPy.Name + "]图层不是面状图层，检查失败！");
                return -1;
            }

            int idxfcodepy = pFeatClsPy.FindField(fcodename);
            if (idxfcodepy == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrPy.Name + "]图层中未找到分类代码[" + fcodeName + "]字段，检查失败！");
                return -1;
            }

            int idxfcodeln = pFeatClsLn.FindField(fcodename);
            if (idxfcodepy == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrLn.Name + "]图层中未找到分类代码[" + fcodeName + "]字段，检查失败！");
                return -1;
            }

            int idxfname = pFeatClsLn.FindField(fnamename);
            if (idxfname == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrLn.Name + "]图层中未找到名称[" + fnamename + "]字段，检查失败！");
                return -1;
            }

            int idxfname2 = pFeatClsPy.FindField(fname2name);
            if (idxfname2 == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrPy.Name + "]图层中未找到名称2[" + fname2name + "]字段，检查失败！");
                return -1;
            }

            int idxfname3 = pFeatClsPy.FindField(fname3name);
            if (idxfname3 == -1)
            {
               LogHelper.WriteErrLog("[" + pFeatLyrPy.Name + "]图层中未找到名称3[" + fname3name + "]字段，检查失败！");
                return -1;
            }

            ISpatialFilter pSpatialFileter = new SpatialFilterClass();
            if (pGeometry != null) pSpatialFileter.Geometry = pGeometry;

            string sql = fcodename + " in('230100500','230500500','240101500','240102500')";
            pSpatialFileter.WhereClause = whereClause == "" ? sql : whereClause + " and " + sql;

            pSpatialFileter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            pSpatialFileter.GeometryField = pFeatClsPy.ShapeFieldName;

            showFakePro(true);
            LogHelper.WriteLog("正在计算需要检查的要素数目...");

            int max = FeatureClassHelper.GetFeatureCountFromLayer(pFeatLyrPy, pSpatialFileter);

            LogHelper.WriteLog("计算完毕。共有" + max + "个要素参与检查。");
            showFakePro(false);

            if (max == 0)
            {
                LogHelper.WriteLog("没有满足检查要求的要素存在。");
                return -1;
            }

            setProcessBarMax(max);

            IFeatureCursor pFeatCur;
            pFeatCur = pFeatLyrPy.Search(pSpatialFileter, false);

            IFeature pFeaturePy;

            int count = 0;
            int errCount = 0;

            while ((pFeaturePy = pFeatCur.NextFeature()) != null)
            {
                if (IsStop()) break;

                setProcessBarCurrent(count);
                count++;

                IFeatureSelection pFeatureSeleciton = pFeatLyrLn as IFeatureSelection ;
                ISelectionSet pSelectionSet = CursorHelper.GetSelset(pFeatureSeleciton, pFeaturePy.ShapeCopy, 
                    fcodename + " = '260801416'", esriSpatialRelEnum.esriSpatialRelIntersects);

                IEnumIDs pIDs = pSelectionSet.IDs;
                pIDs.Reset();
                int id;

                string fnamevalue = "";
                string fname2value = StringHelper.ConvertWRTNull(pFeaturePy.get_Value(idxfname2));
                string fname3value = StringHelper.ConvertWRTNull(pFeaturePy.get_Value(idxfname3));

                IFeature pFeatureLn;

                switch (pSelectionSet.Count)
                {
                    //没有找到结构线，而它的名称2或者名称3属性又不为空，则记为错误
                    case 0:
                        if (fname2value != "" && fname2value != "0")
                        {
                            RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "名称2不应有值");
                            errCount++;
                        }

                        if (fname3value != "" && fname3value != "0")
                        {
                            RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "名称3不应有值");
                            errCount++;
                        }
                        break ;
                    //只找到一段结构线（注：一段结构线和一根结构线是不同的概念）
                    case 1:
                        id = pIDs.Next();
                        pFeatureLn = pFeatClsLn.GetFeature(id);
                        fnamevalue = StringHelper.ConvertWRTNull(pFeatureLn.get_Value(idxfname));
                        if (fnamevalue != fname2value)
                        {
                            RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, pFeatureLn, pFeaturePy.ShapeCopy, "名称2不正确");
                            errCount++;
                        }

                        if (fname3value != "" && fname3value != "0")
                        {
                            RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "名称3不应有值");
                            errCount++;
                        }

                        break;

                    //找到不止一段结构线
                    default :
                        string fnamevalue2 = "";
                        while ((id = pIDs.Next()) != -1)
                        {                            
                            if (IsStop()) break;
                            pFeatureLn = pFeatClsLn.GetFeature(id);

                            string temp = StringHelper.ConvertWRTNull(pFeatureLn.get_Value(idxfname));

                            if (fnamevalue == "") fnamevalue = temp;

                            //当该段结构线的名称和temp不同时
                            if (fnamevalue != temp)
                            {
                                //当fnamevalue2已经被赋值，说明至少有两根不同的结构线存在
                                if (fnamevalue2 != "")
                                {
                                    //该段结构线的名称跟fnamevalue和fnamevalue2都不等，说明有多河经过
                                    if (fnamevalue2 != temp)
                                    {
                                        RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "多河经过");
                                        errCount++;
                                        break;
                                    }
                                }
                                else
                                {
                                    fnamevalue2 = temp;
                                }
                            }

                            //fnamevalue2为空，说明只有一根结构线经过
                            if (fnamevalue2 == "")
                            {
                                if (fnamevalue != fname2value)
                                {
                                    RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, pFeatureLn, pFeaturePy.ShapeCopy, "名称2不正确");
                                    errCount++;
                                }

                                if (fname3value != "" && fname3value != "0")
                                {
                                    RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "名称3不应有值");
                                    errCount++;
                                }
                            }
                            else
                            {
                                //当名称2即不与fnamevalue等，又不与fnamevalue2等，记为名称2错误
                                if (fname2value != fnamevalue && fname2value != fnamevalue2)
                                {
                                    RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "名称2不正确");
                                    errCount++;
                                }

                                //当名称3与名称2相等，记为名称3错误
                                if (fname3value == fname2value)
                                {
                                    RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "名称3不正确");
                                    errCount++;
                                }
                                else 
                                {                                
                                    //当名称3即不与fnamevalue等，又不与fnamevalue2等，记为名称2错误
                                    if (fname3value != fnamevalue && fname3value != fnamevalue2)
                                    {
                                        RecordListHelper.AddRecordItem(errType, pFeatLyrPy, pFeatLyrLn, pFeaturePy, null, pFeaturePy.ShapeCopy, "名称3不正确");
                                        errCount++;

                                        //都判断过了名称3不正确了，就不用判断多河经过了
                                        break;
                                    }

                                }
                            }


                        }
                        break;
                }
                pFeatureSeleciton.Clear();
            }

            finishPro.Invoke();

            DataCheckUtility.ReleaseComObject(pFeaturePy);
            DataCheckUtility.ReleaseComObject(pFeatCur);

            LogHelper.WriteLog("水系名称2(3)不一致检查结束。共发现" + errCount + "处错误！\n");

            return errCount;
        }
    }
}
